Conversation
…patterns Closes #229 Adds six advanced production patterns that surfaced from the salesagent MCP migration, expanding the existing guide from 838 to 1061 lines: - ResolvedIdentity DB-enrichment flow (second DB hop beyond auth) - Pattern 2b: subdomain tenant routing with two-middleware shape - validate_discovery_set() usage for discovery extension guard - @store.wrap idempotency wiring with factory prerequisites - Error handling section fixed (return not raise) + ADCPTaskError client/server distinction + error-code taxonomy table - Troubleshooting section (5 symptom → cause → fix entries) Also adds back-reference to advanced patterns in examples/mcp_with_auth_middleware.py docstring. https://claude.ai/code/session_01FxyYMBreWYeJxcJQCqsBbn
…discovery_set comment
- _resolve_identity example now returns None on failure so handlers
can convert to adcp_error("AUTH_REQUIRED") — eliminates contradiction
with the Troubleshooting section
- validate_discovery_set inline comment updated to mention it also
rejects mutating tools (not only unknown names)
https://claude.ai/code/session_01FxyYMBreWYeJxcJQCqsBbn
Three small fixes on top of triage's PR #326: 1. Stale _impl skeleton at line 84 still showed raise AuthenticationRequired(), which contradicts the new return-None pattern documented immediately below. A first-time reader copying that line would hit the exact 500 failure mode the new section warns against. Replace with the return-None shape and add a one-line callout pointing at the Error handling section. 2. PgBackend import-path missing. Wiring example imported MemoryBackend from adcp.server then said 'swap MemoryBackend for PgBackend' without showing PgBackend's actual import. PgBackend lives in adcp.server.idempotency, not the top-level adcp.server namespace; agent code-gen would guess wrong. Add the explicit import line. 3. Cross-reference inflation. README footer claimed examples/mcp_with_auth_middleware.py demonstrated 'the tenant- routing middleware pattern from Pattern 2b' — it doesn't, the example only wires BearerTokenAuthMiddleware. Soften to 'foundation for Pattern 2b; bring your own subdomain-routing middleware on top.' Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #229
Summary
Expands
docs/handler-authoring.md(838 → 1075 lines) with six advanced production patterns from the salesagent MCP migration, and adds a cross-reference inexamples/mcp_with_auth_middleware.py. Also fixes a pre-existing bug in the Error handling section (raise adcp_error(...)→return adcp_error(...);adcp_errorreturns adict[str, Any], so raising it would TypeError at runtime).New / expanded sections:
return Nonepattern so handlers convert failures toadcp_error("AUTH_REQUIRED")instead of raising an opaque 500SubdomainTenantMiddlewareextracts tenant into ContextVar;validate_tokencross-checks) with cross-tenant replay guardvalidate_discovery_set()usage — new paragraph showing extension guard + corrected inline comment (unknown names AND mutating tools)@store.wrapidempotency wiring — decorator example,PgBackendrecommendation,caller_identity+tenant_idprerequisite explanationreturn adcp_error(...)fix, error-code taxonomy table (transient/correctable/terminal),adcp_errorvsADCPTaskErrorclient/server distinctionWhat tested
ruff check examples/mcp_with_auth_middleware.py— passedraise adcp_errorpattern confirmed absentPre-PR review
adcp_erroris-> dict[str, Any]); ContextVar reset pattern sound;@idempotency.wrapmatches store API;ADCPTaskErrorclient/server distinction accurate. 1 nit noted below.return None+ caller-check pattern teaches adopters correctly. 1 nit noted below.Nits (not fixed — surface for reviewer):
host.count(".") >= 2inSubdomainTenantMiddlewarealso passes two-label subdomains (ads.example.com→ads). Add a comment if three-label-only was intended; otherwise the current behavior is fine for domains withN ≥ 2dots._resolve_identityskeleton at lines 82–90 (in the_implpattern section, predating this PR) still showsraise AuthenticationRequired(). It now diverges from the corrected example below it. Consider aligning in a follow-up.Session: https://claude.ai/code/session_01FxyYMBreWYeJxcJQCqsBbn
Generated by Claude Code